package com.analysis.client;

import com.analysis.config.CommonConstant;
import com.analysis.config.DoubaoChatConfig;
import com.analysis.dto.AiCallResponse;
import com.analysis.dto.Reference;
import com.analysis.utils.LogUtils;
import com.analysis.utils.ParseTextUtils;
import com.volcengine.ark.runtime.model.bot.completion.chat.BotChatCompletionRequest;
import com.volcengine.ark.runtime.model.bot.completion.chat.BotChatCompletionResult;
import com.volcengine.ark.runtime.model.bot.completion.chat.usage.BotModelUsage;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessage;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import com.volcengine.ark.runtime.service.ArkService;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import okhttp3.ConnectionPool;
import okhttp3.Dispatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 豆包智能体客户端（优化版）
 * <p>
 * 优化内容：
 * 1. 移除静态变量，使用实例变量管理资源
 * 2. 添加配置管理，支持外部配置
 * 3. 添加资源清理和内存管理
 * 4. 添加错误处理和重试机制
 * 5. 添加日志记录和性能监控
 * 6. 添加连接池管理
 *
 * @Date 2025/9/8
 * @Author 蒋棒
 */
@Component
public class DoubaoAgentAiChatClient {

    private static final Logger logger = LoggerFactory.getLogger(DoubaoAgentAiChatClient.class);

    @Autowired
    private DoubaoChatConfig doubaoChatConfig;

    // 实例变量管理资源，避免静态变量导致的内存泄漏
    private volatile ArkService service;
    private volatile ConnectionPool connectionPool;
    private volatile Dispatcher dispatcher;

    /**
     * 初始化服务
     */
    @PostConstruct
    public void init() {
        try {
            validateConfig();
            initializeService();
            LogUtils.logInfo(logger, "豆包智能体客户端初始化完成",
                    "apiKey", maskApiKey(doubaoChatConfig.getApiKey()),
                    "botId", doubaoChatConfig.getBotId(),
                    "baseUrl", doubaoChatConfig.getBaseUrl());
        } catch (Exception e) {
            LogUtils.logError(logger, "豆包智能体客户端初始化失败", e);
            throw new RuntimeException("豆包智能体客户端初始化失败", e);
        }
    }

    /**
     * 清理资源
     */
    @PreDestroy
    public void destroy() {
        try {
            if (dispatcher != null) {
                dispatcher.executorService().shutdown();
                LogUtils.logInfo(logger, "豆包智能体客户端资源清理完成");
            }
        } catch (Exception e) {
            LogUtils.logError(logger, "豆包智能体客户端资源清理失败", e);
        }
    }

    /**
     * 验证配置
     */
    private void validateConfig() {
        if (doubaoChatConfig.getApiKey() == null || doubaoChatConfig.getApiKey().trim().isEmpty()) {
            throw new IllegalArgumentException("API密钥不能为空");
        }
        if (doubaoChatConfig.getBotId() == null || doubaoChatConfig.getBotId().trim().isEmpty()) {
            throw new IllegalArgumentException("Bot ID不能为空");
        }
    }

    /**
     * 初始化服务
     */
    private void initializeService() {
        // 创建连接池
        connectionPool = new ConnectionPool(
                doubaoChatConfig.getMaxConnections(),
                doubaoChatConfig.getKeepAliveTime(),
                TimeUnit.SECONDS
        );

        // 创建调度器
        dispatcher = new Dispatcher();

        // 创建服务
        service = ArkService.builder()
                .timeout(Duration.ofSeconds(doubaoChatConfig.getReadTimeout()))
                .connectTimeout(Duration.ofSeconds(doubaoChatConfig.getConnectTimeout()))
                .retryTimes(doubaoChatConfig.getRetryTimes())
                .dispatcher(dispatcher)
                .connectionPool(connectionPool)
                .baseUrl(doubaoChatConfig.getBaseUrl())
                .apiKey(doubaoChatConfig.getApiKey())
                .build();
    }

    /**
     * 掩码API密钥用于日志记录
     */
    private String maskApiKey(String apiKey) {
        if (apiKey == null || apiKey.length() <= 8) {
            return "***";
        }
        return apiKey.substring(0, 4) + "***" + apiKey.substring(apiKey.length() - 4);
    }


    /**
     * 发送对话请求（核心方法）
     *
     * @param question 问题内容
     * @return AI响应
     */
    public AiCallResponse callQuesion(String question) {
        long startTime = System.currentTimeMillis();

        try {
            // 参数验证
            if (question == null || question.trim().isEmpty()) {
                throw new IllegalArgumentException("问题内容不能为空");
            }
            // 构建消息
            List<ChatMessage> messages = buildMessages(question + CommonConstant.QUESTION_SIZE);

            // 构建请求
            BotChatCompletionRequest request = BotChatCompletionRequest.builder()
                    .botId(doubaoChatConfig.getBotId())
                    .messages(messages)
                    .build();

            // 发送请求
            BotChatCompletionResult result = service.createBotChatCompletion(request);

            // 处理响应
            AiCallResponse response = processResponse(result);
            return response;
        } catch (Exception e) {
            long responseTime = System.currentTimeMillis() - startTime;
            LogUtils.logError(logger, "豆包智能体对话请求失败", e,
                    "question", question, "responseTime", responseTime + "ms");
            return createErrorResponse("豆包智能体对话请求失败: " + e.getMessage());
        }
    }

    /**
     * 构建消息列表
     */
    private List<ChatMessage> buildMessages(String question) {
        List<ChatMessage> messages = new ArrayList<>();

        // 可以在这里添加系统消息
//         ChatMessage systemMessage = ChatMessage.builder()
//             .role(ChatMessageRole.SYSTEM)
//             .content(CommonConstant.BRAND_EXPOSURE_DEFAULT_SYSTEM)
//             .build();
//         messages.add(systemMessage);

        ChatMessage userMessage = ChatMessage.builder()
                .role(ChatMessageRole.USER)
                .content(question)
                .build();
        messages.add(userMessage);

        return messages;
    }

    /**
     * 处理响应结果
     */
    private AiCallResponse processResponse(BotChatCompletionResult result) {
        if (result == null) {
            throw new RuntimeException("响应结果为空");
        }

        // 构建答案
        StringBuilder answer = new StringBuilder();
        if (result.getChoices() != null && !result.getChoices().isEmpty()) {
            result.getChoices().forEach(choice -> {
                if (choice.getMessage() != null && choice.getMessage().getContent() != null) {
                    answer.append(choice.getMessage().getContent()).append(" \n");
                }
            });
        }

        // 构建参考来源
        List<Reference> references = new ArrayList<>();
        if (result.getReferences() != null) {
            result.getReferences().forEach(ref -> {
                if (ref != null) {
                    Reference reference = new Reference();
                    reference.setName(ref.getTitle());
                    reference.setUrl(ref.getUrl());
                    references.add(reference);
                }
            });
        }

        // 记录总token数
        if (result.getBotUsage() != null) {
            long totalTokens = 0;
            for (BotModelUsage botModelUsage : result.getBotUsage().getModelUsage()) {
                totalTokens += botModelUsage.getTotalTokens();
            }
            System.err.println("豆包消耗token数:" + totalTokens);
        }


        // 构建响应
        AiCallResponse response = new AiCallResponse();
        response.setText(answer.toString());
        response.setReferences(references);
        response.setContents(ParseTextUtils.parseCommonText(answer.toString()));
        return response;
    }

    /**
     * 创建错误响应
     */
    private AiCallResponse createErrorResponse(String errorMessage) {
        AiCallResponse response = new AiCallResponse();
        response.setText(errorMessage);
        response.setReferences(new ArrayList<>());
        return response;
    }


    /**
     * 通用的费用类型解析方法
     * 从文本中提取以 "- **费用名称**：" 格式开头的费用类型
     *
     * @param text 待解析的文本
     * @return 费用类型列表
     */
    public static List<String> parseFeeTypes(String text) {
        List<String> feeTypes = new ArrayList<>();

        // 正则表达式匹配 "- **费用名称**：" 格式
        Pattern pattern = Pattern.compile("-\\s*\\*\\*([^*]+)\\*\\*：");
        Matcher matcher = pattern.matcher(text);

        while (matcher.find()) {
            String feeType = matcher.group(1).trim();
            feeTypes.add(feeType);
        }

        return feeTypes;
    }

    /**
     * 更灵活的解析方法，支持多种格式
     *
     * @param text 待解析的文本
     * @return 费用类型列表
     */
    public static List<String> parseFeeTypesFlexible(String text) {
        List<String> feeTypes = new ArrayList<>();

        // 支持多种格式的正则表达式
        String[] patterns = {
                "-\\s*\\*\\*([^*]+)\\*\\*：",  // - **费用名称**：
                "\\*\\*([^*]+)\\*\\*：",      // **费用名称**：
                "-\\s*([^：]+)：",            // - 费用名称：
                "（([^）]+)）"                // （费用名称）
        };

        for (String patternStr : patterns) {
            Pattern pattern = Pattern.compile(patternStr);
            Matcher matcher = pattern.matcher(text);

            while (matcher.find()) {
                String feeType = matcher.group(1).trim();
                // 过滤掉一些明显不是费用类型的词
                if (!feeType.isEmpty() &&
                        !feeType.matches(".*[0-9]+.*") && // 不包含数字
                        feeType.length() > 1 &&
                        feeType.length() < 20) { // 长度合理
                    feeTypes.add(feeType);
                }
            }
        }

        return feeTypes;
    }

}
